﻿using System;
using System.Threading;

namespace Rpc.Abstractions
{
    public class RpcOptions
    {
        public static RpcOption<int> ThreadPool_MinThreads { get; } = new RpcOption<int>(() =>
        {
            ThreadPool.GetMinThreads(out var min, out _);
            return min;
        });

        public static RpcOption<int> ThreadPool_CompletionPortThreads { get; } = new RpcOption<int>(() =>
        {
            ThreadPool.GetMinThreads(out _, out var completion);
            return completion;
        });

        public static RpcOption<TimeSpan> Consul_Node_Status_Refresh_Interval { get; } =
            new RpcOption<TimeSpan>(TimeSpan.FromSeconds(10));

        public static RpcOption<int> Server_DotNetty_Channel_SoBacklog { get; } = new RpcOption<int>(100);

        public static RpcOption<TimeSpan> DotNetty_Connect_Timeout { get; } =
            new RpcOption<TimeSpan>(TimeSpan.FromSeconds(1));

        public static RpcOption<bool> DotNetty_Enable_Libuv { get; } = new RpcOption<bool>(false);

        public static RpcOption<int> DotNetty_Event_Loop_Count { get; } = new RpcOption<int>(() =>
        {
            ThreadPool.GetMinThreads(out var min, out _);
            return min;
        });

        public static RpcOption<TimeSpan> Remoting_Invoke_CancellationTokenSource_Timeout { get; } = new RpcOption<TimeSpan>(TimeSpan.FromSeconds(60));

        public static RpcOption<bool> Output_DynamicProxy_SourceCode { get; } = new RpcOption<bool>(false);


        public static void SetOption<T>(RpcOption<T> option, T value)
        {
            option.Value = value;
        }

        public static void SetOption<T>(RpcOption<T> option, Func<T> func)
        {
            option.Value = func();
        }
    }

    public class RpcOption<T>
    {
        public RpcOption(T value)
        {
            Value = value;
        }

        public RpcOption(Func<T> func)
        {
            Value = func();
        }

        public T Value { get; internal set; }
    }
}
